// package: rewords-server-2024
// filename: xpool
// author: diogoxiang@gmail.com
// time: 2024/7/26 上午10:38

package xpool

import (
	"context"
	"time"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/silenceper/pool"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"

	"rewords-server-2024/internal/model"
	"rewords-server-2024/internal/service"
)

var (
	GMongoPool pool.Pool
)

// InitMongoPool mongo 链接池
func InitMongoPool() {
	mongoConf, err := service.SysConfig().GetMongoConfig(context.Background())
	if err != nil {
		panic(err)
	}
	//创建一个连接池： 初始化5，最大链接30
	//创建一个连接池： 初始化5，最大空闲连接是20，最大并发连接30
	poolConfig := &pool.Config{
		InitialCap: mongoConf.InitialCap, //资源池初始连接数
		MaxIdle:    mongoConf.PoolSize,   //最大空闲连接数
		MaxCap:     mongoConf.MaxCap,     //最大并发连接数
		Factory:    Factory,
		Close:      Close,
		Ping:       Ping,
		// 连接最大空闲时间，超过该时间的连接 将会关闭，可避免空闲时连接EOF，自动失效的问题
		IdleTimeout: mongoConf.ConnectTimeout * time.Second,
	}
	p, err := pool.NewChannelPool(poolConfig)
	if err != nil {
		g.Log().Warning(context.Background(), "链接 MongoDB 失败：", err)
	}
	GMongoPool = p
}

func Factory() (interface{}, error) {
	var (
		client    *mongo.Client
		mongoConf *model.MongoConf
		ctx       context.Context
		err       error
	)

	//mongoConf = config.GConfig.Mongo
	mongoConf, err = service.SysConfig().GetMongoConfig(context.Background())

	ctx, _ = context.WithTimeout(context.TODO(), mongoConf.ConnectTimeout*time.Second)

	// 建立mongodb连接
	g.Log().Info(ctx, "GMongo pool 建立mongodb连接")
	if client, err = mongo.Connect(ctx, options.Client().ApplyURI(mongoConf.Uri)); err != nil {
		g.Log().Warning(ctx, "链接 MongoDB 失败：", err)
		return nil, err
	}

	if err = client.Ping(ctx, nil); err != nil {
		g.Log().Warning(ctx, "ping MongoDB 失败：", err)
		return nil, err
	}
	return client, nil
}

func Close(v interface{}) error {
	return v.(*mongo.Client).Disconnect(context.TODO())
}

func Ping(v interface{}) error {
	return v.(*mongo.Client).Ping(context.TODO(), nil)
}
